home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / Libnet-0.99b / src / checksum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  2.3 KB  |  112 lines

  1. /*
  2.  * $Id: checksum.c,v 1.3 1999/05/28 14:30:45 dugsong Exp $
  3.  *
  4.  * checksum.c - IP checksum routines
  5.  *
  6.  * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
  7.  * All rights reserved, all wrongs reversed.
  8.  *
  9.  * Disclaimer: i claim dis.
  10.  */
  11.  
  12. #if (HAVE_CONFIG_H)
  13. #include "../include/config.h"
  14. #endif
  15. #include "../include/libnet.h"
  16.  
  17. #define CKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), \
  18.             (~(x + (x >> 16)) & 0xffff))
  19.  
  20. int
  21. in_cksum(u_short *addr, int len)
  22. {
  23.   int sum = 0;
  24.   int nleft = len;
  25.   u_short tmp = 0, *w = addr;
  26.   
  27.   while (nleft > 1)  {
  28.     sum += *w++;
  29.     nleft -= 2;
  30.   }
  31.   if (nleft == 1) {
  32.     *(u_char *)(&tmp) = *(u_char *)w;
  33.     sum += tmp;
  34.   }
  35.   return (sum);
  36. }
  37.  
  38. int
  39. do_checksum(u_char *buf, int protocol, int len)
  40. {
  41.   struct ip *iph = (struct ip *)buf;
  42.   int ip_hl = iph->ip_hl * 4;
  43.   int sum;
  44.   
  45.   switch (protocol) {
  46.  
  47.   case IPPROTO_TCP:
  48.     {
  49.       struct tcphdr *tcph = (struct tcphdr *)(buf + ip_hl);
  50.       
  51.       tcph->th_sum = 0;
  52.       sum = in_cksum((u_short *)&iph->ip_src, 8);
  53.       sum += ntohs(IPPROTO_TCP + len);
  54.       sum += in_cksum((u_short *)tcph, len);
  55.       tcph->th_sum = CKSUM_CARRY(sum);
  56.       break;
  57.     }
  58.   case IPPROTO_UDP:
  59.     {
  60.       struct udphdr *udph = (struct udphdr *)(buf + ip_hl);
  61.  
  62.       udph->uh_sum = 0;
  63.       sum = in_cksum((u_short *)&iph->ip_src, 8);
  64.       sum += ntohs(IPPROTO_UDP + len);
  65.       sum += in_cksum((u_short *)udph, len);
  66.       udph->uh_sum = CKSUM_CARRY(sum);
  67.       break;
  68.     }
  69.   case IPPROTO_ICMP:
  70.     {
  71.       struct libnet_icmp_hdr *icmph = (struct libnet_icmp_hdr *)(buf + ip_hl);
  72.  
  73.       icmph->icmp_sum = 0;
  74.       sum = in_cksum((u_short *)icmph, len);
  75.       icmph->icmp_sum = CKSUM_CARRY(sum);
  76.       break;
  77.     }
  78.   case IPPROTO_IGMP:
  79.     {
  80.       struct libnet_igmp_hdr *igmph = (struct libnet_igmp_hdr *)(buf + ip_hl);
  81.  
  82.       igmph->igmp_sum = 0;
  83.       sum = in_cksum((u_short *)igmph, len);
  84.       igmph->igmp_sum = CKSUM_CARRY(sum);
  85.       break;
  86.     }
  87.   case IPPROTO_IP:
  88.     iph->ip_sum = 0;
  89.     sum = in_cksum((u_short *)iph, len);
  90.     iph->ip_sum = CKSUM_CARRY(sum);
  91.     break;
  92.  
  93.   default:
  94. #if (__DEBUG)
  95.     fprintf(stderr, "do_checksum: UNSUPPORTED protocol %d\n", protocol);
  96. #endif
  97.     break;
  98.   }
  99.   return (1);
  100. }
  101.  
  102. u_short
  103. ip_check(u_short *addr, int len)
  104. {
  105.   int sum;
  106.  
  107.   sum = in_cksum(addr, 5);
  108.   sum += in_cksum(addr + 6, len - 7);
  109.  
  110.   return CKSUM_CARRY(sum);
  111. }
  112.